package com.hoe.tsb.fraft.client.role;

import com.hoe.tsb.Configuration;
import com.hoe.tsb.fraft.client.ClientRoleBridge;
import com.hoe.tsb.fraft.enums.RoleType;
import com.hoe.tsb.fraft.event.msg.FRaftMessage;
import lombok.extern.slf4j.Slf4j;

import java.util.Random;

/**
 * <p>
 * 跟随者角色
 * </p>
 *
 * @author hoe
 * @version 1.0
 * @date 2022/12/5 14:34
 */
@Slf4j
public class Follower extends SupportRole {

    public Follower(ClientRoleBridge bridge, Configuration configuration, RoleObserver roleObserver) {
        super(bridge, configuration, roleObserver);

        //启动线程随机生成切换Candidate时间
        new Thread(() -> {
            //最终的切换candidate等待时间就是 timeout ~ 1.5*timeout
            int randResetMill = new Random().nextInt(mConfig.getTimeout() / 2);
            try {
                Thread.sleep(randResetMill);
            } catch (InterruptedException e) {
                //ignore ...
            }

            resetTimeout();
        }).start();
    }

    @Override
    protected void doTimeout() {
        turnTo(RoleType.CANDIDATE);
    }

    @Override
    public boolean handleMessage(FRaftMessage msg) {
        if (super.handleMessage(msg)) {
            return true;
        }

        //如果发送方是Leader，则重置超时倒计时
        if (msg.getRoleType() == RoleType.LEADER) {
            log.debug("收到Leader的消息，重置超时倒计时，leader ip：{}，port：{}", msg.getNodes().get(0).getIp(), msg.getNodes().get(0).getPort());
            resetTimeout();
            mBridge.markLeader(msg.getNodes().get(0).getIp(), msg.getNodes().get(0).getPort());
            //解决任期会落后Leader的问题
            mRoleObserver.setTerm(msg.getTerm());
        }

        return false;
    }

}
